﻿using Daemon.Common.Auth;
using Daemon.Data.Infrastructure.Auth;
using Daemon.Data.Substructure.Const;
using Daemon.Model;
using Daemon.Repository.Contract;
using Daemon.Service.Contract;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Daemon.Service
{
	public class AuthInfoService : IAuthInfoService
	{
		private const string INVALID_LOGIN_MESSAGE = "用户名或者密码错误!";

		private readonly IClientConfigRepository _clientConfigRepository;

		private readonly IUserAuthorizationService _userAuthorizationService;

		private readonly ClientAuthCache _clientAuthCache;

		private readonly IApplicationRepository _applicationRepository;

		public AuthInfoService(IClientConfigRepository clientConfigRepository,
			IUserAuthorizationService userAuthorizationService,
			IApplicationRepository applicationRepository,
			ClientAuthCache clientAuthCache)
		{
			_clientConfigRepository = clientConfigRepository;
			_userAuthorizationService = userAuthorizationService;
			_applicationRepository = applicationRepository;
			_clientAuthCache = clientAuthCache;
		}

		public (BaseAuthUser user, HttpStatusCode state, string message) GetLoginUser(string prefix, string username, string password)
		{
			BaseAuthUser userEntity = JsonConvert.DeserializeObject<BaseAuthUser>(JsonConvert.SerializeObject(_userAuthorizationService.GetUserEntity(username, password, out string error)));
			return CheckLoginUser(userEntity, prefix, username, error);
		}

		public (BaseAuthUser user, HttpStatusCode state, string message) GetLoginUserByEmail(string prefix, string email)
		{
			BaseAuthUser userEntity = JsonConvert.DeserializeObject<BaseAuthUser>(JsonConvert.SerializeObject(_userAuthorizationService.GetUserEntityByEmail(email, out string error)));
			return CheckLoginUser(userEntity, prefix, userEntity?.UserName, error);
		}

		private (BaseAuthUser user, HttpStatusCode state, string message) CheckLoginUser(BaseAuthUser userEntity, string prefix, string username, string error)
		{
			if (!string.IsNullOrEmpty(error))
			{
				return (null, HttpStatusCode.Unauthorized, error);
			}

			if (userEntity == null)
			{
				return (null, HttpStatusCode.Unauthorized, SystemConst.NO_USER);
			}

			if (userEntity.Deactivated)
			{
				return (null, HttpStatusCode.Unauthorized, "你的账户已被禁用!");
			}

			var authInfo = new AuthInfoEF(userEntity);
			_clientAuthCache.AddClientUserEntryAsync(username, authInfo);
			if (authInfo.AuthorizationTree.TryGetValue("applications", out JToken apps) && !apps.Values<string>().Contains(prefix))
			{
				var appName = _applicationRepository.GetApplicationName(prefix);
				string message;
				if (string.IsNullOrEmpty(appName))
				{
					message = "Have no permission to this product";
					return (null, HttpStatusCode.Unauthorized, message);
				}

				message = $"该用户没有{appName}的权限. 请联系管理员！";

				return (null, HttpStatusCode.Unauthorized, message);
			}

			return (userEntity, HttpStatusCode.Created, "Authorized");
		}
	}
}
